home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / cvs-1_3.lha / cvs-1.3 / src / classify.c < prev    next >
C/C++ Source or Header  |  1992-03-31  |  9KB  |  381 lines

  1. /*
  2.  * Copyright (c) 1992, Brian Berliner and Jeff Polk
  3.  * Copyright (c) 1989-1992, Brian Berliner
  4.  * 
  5.  * You may distribute under the terms of the GNU General Public License as
  6.  * specified in the README file that comes with the CVS 1.3 kit.
  7.  * 
  8.  */
  9.  
  10. #include "cvs.h"
  11.  
  12. #ifndef lint
  13. static char rcsid[] = "@(#)classify.c 1.11 92/03/31";
  14. #endif
  15.  
  16. #if __STDC__
  17. static void sticky_ck (char *file, int aflag, Vers_TS * vers, List * entries);
  18. #else
  19. static void sticky_ck ();
  20. #endif                /* __STDC__ */
  21.  
  22. /*
  23.  * Classify the state of a file
  24.  */
  25. Ctype
  26. Classify_File (file, tag, date, options, force_tag_match, aflag, repository,
  27.            entries, srcfiles, versp)
  28.     char *file;
  29.     char *tag;
  30.     char *date;
  31.     char *options;
  32.     int force_tag_match;
  33.     int aflag;
  34.     char *repository;
  35.     List *entries;
  36.     List *srcfiles;
  37.     Vers_TS **versp;
  38. {
  39.     Vers_TS *vers;
  40.     Ctype ret;
  41.  
  42.     /* get all kinds of good data about the file */
  43.     vers = Version_TS (repository, options, tag, date, file,
  44.                force_tag_match, 0, entries, srcfiles);
  45.  
  46.     if (vers->vn_user == NULL)
  47.     {
  48.     /* No entry available, ts_rcs is invalid */
  49.     if (vers->vn_rcs == NULL)
  50.     {
  51.         /* there is no RCS file either */
  52.         if (vers->ts_user == NULL)
  53.         {
  54.         /* there is no user file */
  55.         if (!force_tag_match || !(vers->tag || vers->date))
  56.             if (!really_quiet)
  57.             error (0, 0, "nothing known about %s", file);
  58.         ret = T_UNKNOWN;
  59.         }
  60.         else
  61.         {
  62.         /* there is a user file */
  63.         if (!force_tag_match || !(vers->tag || vers->date))
  64.             if (!really_quiet)
  65.             error (0, 0, "use `cvs add' to create an entry for %s",
  66.                    file);
  67.         ret = T_UNKNOWN;
  68.         }
  69.     }
  70.     else
  71.     {
  72.         /* there is an rcs file */
  73.  
  74.         if (vers->ts_user == NULL)
  75.         {
  76.         /* There is no user file; needs checkout */
  77.         ret = T_CHECKOUT;
  78.         }
  79.         else
  80.         {
  81.         /*
  82.          * There is a user file; print a warning and add it to the
  83.          * conflict list, only if it is indeed different from what we
  84.          * plan to extract
  85.          */
  86.         if (No_Difference (file, vers, entries))
  87.         {
  88.             /* the files were different so it is a conflict */
  89.             if (!really_quiet)
  90.             error (0, 0, "move away %s; it is in the way", file);
  91.             ret = T_CONFLICT;
  92.         }
  93.         else
  94.             /* since there was no difference, still needs checkout */
  95.             ret = T_CHECKOUT;
  96.         }
  97.     }
  98.     }
  99.     else if (strcmp (vers->vn_user, "0") == 0)
  100.     {
  101.     /* An entry for a new-born file; ts_rcs is dummy */
  102.  
  103.     if (vers->ts_user == NULL)
  104.     {
  105.         /*
  106.          * There is no user file, but there should be one; remove the
  107.          * entry
  108.          */
  109.         if (!really_quiet)
  110.         error (0, 0, "warning: new-born %s has disappeared", file);
  111.         ret = T_REMOVE_ENTRY;
  112.     }
  113.     else
  114.     {
  115.         /* There is a user file */
  116.  
  117.         if (vers->vn_rcs == NULL)
  118.         /* There is no RCS file, added file */
  119.         ret = T_ADDED;
  120.         else
  121.         {
  122.         /*
  123.          * There is an RCS file, so someone else must have checked
  124.          * one in behind our back; conflict
  125.          */
  126.         if (!really_quiet)
  127.             error (0, 0,
  128.             "conflict: %s created independently by second party",
  129.                file);
  130.         ret = T_CONFLICT;
  131.         }
  132.     }
  133.     }
  134.     else if (vers->vn_user[0] == '-')
  135.     {
  136.     /* An entry for a removed file, ts_rcs is invalid */
  137.  
  138.     if (vers->ts_user == NULL)
  139.     {
  140.         char tmp[PATH_MAX];
  141.  
  142.         /* There is no user file (as it should be) */
  143.  
  144.         (void) sprintf (tmp, "-%s", vers->vn_rcs ? vers->vn_rcs : "");
  145.  
  146.         if (vers->vn_rcs == NULL)
  147.         {
  148.  
  149.         /*
  150.          * There is no RCS file; this is all-right, but it has been
  151.          * removed independently by a second party; remove the entry
  152.          */
  153.         ret = T_REMOVE_ENTRY;
  154.         }
  155.         else if (strcmp (tmp, vers->vn_user) == 0)
  156.  
  157.         /*
  158.          * The RCS file is the same version as the user file was, and
  159.          * that's OK; remove it
  160.          */
  161.         ret = T_REMOVED;
  162.         else
  163.         {
  164.  
  165.         /*
  166.          * The RCS file is a newer version than the removed user file
  167.          * and this is definitely not OK; make it a conflict.
  168.          */
  169.         if (!really_quiet)
  170.             error (0, 0,
  171.                "conflict: removed %s was modified by second party",
  172.                file);
  173.         ret = T_CONFLICT;
  174.         }
  175.     }
  176.     else
  177.     {
  178.         /* The user file shouldn't be there */
  179.         if (!really_quiet)
  180.         error (0, 0, "%s should be removed and is still there", file);
  181.         ret = T_REMOVED;
  182.     }
  183.     }
  184.     else
  185.     {
  186.     /* A normal entry, TS_Rcs is valid */
  187.     if (vers->vn_rcs == NULL)
  188.     {
  189.         /* There is no RCS file */
  190.  
  191.         if (vers->ts_user == NULL)
  192.         {
  193.         /* There is no user file, so just remove the entry */
  194.         if (!really_quiet)
  195.             error (0, 0, "warning: %s is not (any longer) pertinent",
  196.                file);
  197.         ret = T_REMOVE_ENTRY;
  198.         }
  199.         else if (strcmp (vers->ts_user, vers->ts_rcs) == 0)
  200.         {
  201.  
  202.         /*
  203.          * The user file is still unmodified, so just remove it from
  204.          * the entry list
  205.          */
  206.         if (!really_quiet)
  207.             error (0, 0, "%s is no longer in the repository", file);
  208.         ret = T_REMOVE_ENTRY;
  209.         }
  210.         else
  211.         {
  212.         /*
  213.          * The user file has been modified and since it is no longer
  214.          * in the repository, a conflict is raised
  215.          */
  216.         if (No_Difference (file, vers, entries))
  217.         {
  218.             /* they are different -> conflict */
  219.             if (!really_quiet)
  220.             error (0, 0,
  221.            "conflict: %s is modified but no longer in the repository",
  222.                file);
  223.             ret = T_CONFLICT;
  224.         }
  225.         else
  226.         {
  227.             /* they weren't really different */
  228.             if (!really_quiet)
  229.             error (0, 0,
  230.                    "warning: %s is not (any longer) pertinent",
  231.                    file);
  232.             ret = T_REMOVE_ENTRY;
  233.         }
  234.         }
  235.     }
  236.     else if (strcmp (vers->vn_rcs, vers->vn_user) == 0)
  237.     {
  238.         /* The RCS file is the same version as the user file */
  239.  
  240.         if (vers->ts_user == NULL)
  241.         {
  242.  
  243.         /*
  244.          * There is no user file, so note that it was lost and
  245.          * extract a new version
  246.          */
  247.         if (strcmp (command_name, "update") == 0)
  248.             if (!really_quiet)
  249.             error (0, 0, "warning: %s was lost", file);
  250.         ret = T_CHECKOUT;
  251.         }
  252.         else if (strcmp (vers->ts_user, vers->ts_rcs) == 0)
  253.         {
  254.  
  255.         /*
  256.          * The user file is still unmodified, so nothing special at
  257.          * all to do -- no lists updated, unless the sticky -k option
  258.          * has changed.  If the sticky tag has changed, we just need
  259.          * to re-register the entry
  260.          */
  261.         if (vers->entdata->options &&
  262.             strcmp (vers->entdata->options, vers->options) != 0)
  263.             ret = T_CHECKOUT;
  264.         else
  265.         {
  266.             sticky_ck (file, aflag, vers, entries);
  267.             ret = T_UPTODATE;
  268.         }
  269.         }
  270.         else
  271.         {
  272.  
  273.         /*
  274.          * The user file appears to have been modified, but we call
  275.          * No_Difference to verify that it really has been modified
  276.          */
  277.         if (No_Difference (file, vers, entries))
  278.         {
  279.  
  280.             /*
  281.              * they really are different; modified if we aren't
  282.              * changing any sticky -k options, else needs merge
  283.              */
  284. #ifdef XXX_FIXME_WHEN_RCSMERGE_IS_FIXED
  285.             if (strcmp (vers->entdata->options ?
  286.                vers->entdata->options : "", vers->options) == 0)
  287.             ret = T_MODIFIED;
  288.             else
  289.             ret = T_NEEDS_MERGE;
  290. #else
  291.             ret = T_MODIFIED;
  292.             sticky_ck (file, aflag, vers, entries);
  293. #endif
  294.         }
  295.         else
  296.         {
  297.             /* file has not changed; check out if -k changed */
  298.             if (strcmp (vers->entdata->options ?
  299.                vers->entdata->options : "", vers->options) != 0)
  300.             {
  301.             ret = T_CHECKOUT;
  302.             }
  303.             else
  304.             {
  305.  
  306.             /*
  307.              * else -> note that No_Difference will Register the
  308.              * file already for us, using the new tag/date. This
  309.              * is the desired behaviour
  310.              */
  311.             ret = T_UPTODATE;
  312.             }
  313.         }
  314.         }
  315.     }
  316.     else
  317.     {
  318.         /* The RCS file is a newer version than the user file */
  319.  
  320.         if (vers->ts_user == NULL)
  321.         {
  322.         /* There is no user file, so just get it */
  323.  
  324.         if (strcmp (command_name, "update") == 0)
  325.             if (!really_quiet)
  326.             error (0, 0, "warning: %s was lost", file);
  327.         ret = T_CHECKOUT;
  328.         }
  329.         else if (strcmp (vers->ts_user, vers->ts_rcs) == 0)
  330.         {
  331.  
  332.         /*
  333.          * The user file is still unmodified, so just get it as well
  334.          */
  335.         ret = T_CHECKOUT;
  336.         }
  337.         else
  338.         {
  339.         if (No_Difference (file, vers, entries))
  340.             /* really modified, needs to merge */
  341.             ret = T_NEEDS_MERGE;
  342.         else
  343.             /* not really modified, check it out */
  344.             ret = T_CHECKOUT;
  345.         }
  346.     }
  347.     }
  348.  
  349.     /* free up the vers struct, or just return it */
  350.     if (versp != (Vers_TS **) NULL)
  351.     *versp = vers;
  352.     else
  353.     freevers_ts (&vers);
  354.  
  355.     /* return the status of the file */
  356.     return (ret);
  357. }
  358.  
  359. static void
  360. sticky_ck (file, aflag, vers, entries)
  361.     char *file;
  362.     int aflag;
  363.     Vers_TS *vers;
  364.     List *entries;
  365. {
  366.     if (aflag || vers->tag || vers->date)
  367.     {
  368.     char *enttag = vers->entdata->tag;
  369.     char *entdate = vers->entdata->date;
  370.  
  371.     if ((enttag && vers->tag && strcmp (enttag, vers->tag)) ||
  372.         ((enttag && !vers->tag) || (!enttag && vers->tag)) ||
  373.         (entdate && vers->date && strcmp (entdate, vers->date)) ||
  374.         ((entdate && !vers->date) || (!entdate && vers->date)))
  375.     {
  376.         Register (entries, file, vers->vn_user, vers->ts_rcs,
  377.               vers->options, vers->tag, vers->date);
  378.     }
  379.     }
  380. }
  381.